﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Red.GameData
{
    /// <summary>
    /// Edition context for the game data
    /// Used for edition of many, usually connected objects
    /// Holds internal undo/redo list
    /// Please DO Dispose() this objects manually - keeping them alive for to long is wasting a lot of resources
    /// </summary>
    public class EditorContext : IDisposable
    {
        /// <summary>
        /// Data collection for the edited data
        /// </summary>
        public Raw.DataCollection Data { get; private set; }

        /// <summary>
        /// Reflection setup for the data
        /// </summary>
        public Raw.ReflectionData Reflection { get; private set; }

        /// <summary>
        /// Synchronization group in case we want to have some UI refreshed
        /// May be NULL if no synchronization was requested
        /// </summary>
        public Red.Core.DataConsistency.StateGroup SyncGroup { get; private set; }

        /// <summary>
        /// History of actions executed on this edition context
        /// All operations on objects are always executed though actions for easier undo/redo
        /// Each editor context has it's own undo/redo list although it's quite possible we may cause data validation problems by it :(
        /// </summary>
        public Red.Core.UndoRedo.ActionHistory ActionHistory { get; private set; }

        /// <summary>
        /// Initialize, hidden, please use the EditorEnvironment.CreateContext method
        /// </summary>
        internal EditorContext(Raw.DataCollection data, Raw.ReflectionData reflection, bool createSyncGroup)
        {
            Data = data;
            Reflection = reflection;

            // create synchronization group for ensuring data consistency in this editor context
            if (createSyncGroup)
                SyncGroup = Red.Core.DataConsistency.StateSynchronizer.TheInstance.CreateGroup("EditorContext");

            // create action history for local undo/redo
            ActionHistory = new Red.Core.UndoRedo.ActionHistory();
        }

        /// <summary>
        /// Cleanup
        /// </summary>
        public void Dispose()
        {
            CleanupSyncGroup();
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Internal cleanup
        /// </summary>
        private void CleanupSyncGroup()
        {
            if (SyncGroup != null)
            {
                SyncGroup.Dispose();
                SyncGroup = null;
            }
        }
    }
}
